﻿//-------------------------------------------------------------------
//	Copyright (c) 2010-2013  Zhirnov Andrey
//	This file is part of the "UX Standard Lib" project.
//	See copyright notice in "UX_STL_Ext.h".
//-------------------------------------------------------------------

#ifndef _UXS_GLES_COMMON_H
#define _UXS_GLES_COMMON_H

#include "GLESEnums.h"

namespace UX_STL
{
namespace GLESshell
{
	using namespace UXTypesExt;


	class GLESRenderTarget;
	class GLESTexture;
	class GLESRenderBuffer;
	class GLESFrameBuffer;
	class GLESDefaultFrameBuffer;
	class GLESSamplerSW;

	
#pragma pack(push, 1)

	//
	// Vertex Attrib
	//

	struct GLESVertexAttrib
	{
		uint				uOffset;
		uint16				uStride;
		uint16				uDivisor;
		gl_vertex::type		eType;
		uint8				uLocation;
		uint8				uCount;
		bool				bNormalize	: 1;	// can be true if bInteger and bLong is false
		bool				bInteger	: 1;
		bool				bLong		: 1;
		///
		GLESVertexAttrib():
			uCount(0), uStride(0), uOffset(0), eType(gl_vertex::FLOAT), uDivisor(0),
			uLocation(-1), bNormalize(false), bInteger(false), bLong(false) {}
		
		GLESVertexAttrib(uint8 loc, uint8 count, uint16 stride, uint offset, gl_vertex::type vert, bool norm = false,
						bool b_int = false, bool b_long = false, uint16 divisor = 0):
			uCount(count), uStride(stride), uOffset(offset), eType(vert), uDivisor(divisor),
			uLocation(loc), bNormalize(norm), bInteger(b_int), bLong(b_long) {}
	};


	//
	// Vertex Attrib Extended
	//

	struct GLESVertexAttribExt
	{
		GLuint				uBuffer;
		uint				uOffset;
		uint16				uStride;
		uint16				uDivisor;
		gl_vertex::type		eType;
		uint8				uLocation;
		uint8				uCount;
		bool				bNormalize	: 1;	// can be true if bInteger and bLong is false
		bool				bInteger	: 1;
		bool				bLong		: 1;
		///
		GLESVertexAttribExt():
			uBuffer(0), uCount(0), uStride(0), uOffset(0), eType(gl_vertex::FLOAT), uDivisor(0),
			uLocation(-1), bNormalize(false), bInteger(false), bLong(false) {}
		
		GLESVertexAttribExt(GLuint buf, const GLESVertexAttrib &attr):
			uBuffer(buf), uCount(attr.uCount), uStride(attr.uStride), uOffset(attr.uOffset),
			eType(attr.eType), bNormalize(attr.bNormalize), uDivisor(attr.uDivisor),
			uLocation(attr.uLocation), bInteger(attr.bInteger), bLong(attr.bLong) {}

		GLESVertexAttribExt(GLuint buf, uint8 loc, uint8 count, uint16 stride, uint offset, gl_vertex::type vert,
						  bool norm, bool b_int = false, bool b_long = false, uint16 divisor = 0):
			uBuffer(buf), uCount(count), uStride(stride), uOffset(offset), eType(vert), bNormalize(norm),
			uDivisor(divisor), uLocation(loc), bLong(b_long), bInteger(b_int) {}
	};


	//
	// Vertex Attrib Info
	//

	struct GLESVertexAttribInfo
	{
		gl_vertex::type		eType;
		uint8				uLocation;
		uint8				uCount;
		///
		GLESVertexAttribInfo():
			eType(gl_vertex::FLOAT), uLocation(-1), uCount(0) {}

		GLESVertexAttribInfo(uint8 loc, uint8 count, gl_vertex::type type):
			eType(type), uLocation(loc), uCount(count) {}

		GLESVertexAttribInfo(const GLESVertexAttrib &attr):
			eType(attr.bNormalize ? gl_vertex::FLOAT : attr.eType), uLocation(attr.uLocation), uCount(attr.uCount) {}

		GLESVertexAttribInfo(const GLESVertexAttribExt &attr):
			eType(attr.bNormalize ? gl_vertex::FLOAT : attr.eType), uLocation(attr.uLocation), uCount(attr.uCount) {}

		bool operator > (const GLESVertexAttribInfo &right) const {
			return uLocation > right.uLocation;
		}

		bool operator == (const GLESVertexAttribInfo &right) const {
			return eType == right.eType && uLocation == right.uLocation && uCount == right.uCount;
		}

		bool operator != (const GLESVertexAttribInfo &right) const {
			return !( *this == right );
		}
	};

	
	//
	// Texture Layer
	//
	
	struct GLESTexLayer
	{
		gl_texture::type	eTarget;
		GLuint				uID;
		///
		GLESTexLayer(): eTarget(gl_texture::TEXTURE_2D), uID(0) {}
		GLESTexLayer(gl_texture::type target, GLuint id): eTarget(target), uID(id) {}
	};

#pragma pack(pop)


	typedef array< GLESVertexAttrib >		GLESVerticesAttribs_t;
	typedef array< GLESVertexAttribExt >	GLESVerticesAttribsExt_t;
	typedef array< GLESVertexAttribInfo >	GLESVerticesAttribsInfo_t;
	//typedef array< GLESBuffer *>			GLESBuffers_t;
	
	typedef static_array< GLESVertexAttribInfo, UX_MAX_VERTEX_ATTRIBS >	va_info_array_t;
	typedef static_array< GLESVertexAttribExt, UX_MAX_VERTEX_ATTRIBS >	va_array_t;


	
#ifdef UX_GLES_BASEOBJECT_OVERRIDE
	UX_GLES_BASEOBJECT_OVERRIDE
#else
# ifndef UX_GLES_BASEOBJECT_DEFINED
	
	//
	// GLES Base Object
	//

	class _EXPORT_ GLESBaseObject
	{
	private:
		GLESBaseObject(const GLESBaseObject &) {}
		void operator = (const GLESBaseObject &) {}

	public:
		GLESBaseObject() {}
		virtual ~GLESBaseObject() {}
		virtual void Release() { delete this; }

		//virtual void Destroy() = 0;
		//virtual bool IsValid() const = 0;
	};

# endif	// UX_GLES_BASEOBJECT_DEFINED
#endif	// UX_GLES_BASEOBJECT_OVERRIDE

//-------------------------------------------------------------------

}	// GLESshell
}	// UX_STL

#endif	// _UXS_GLES_COMMON_H
